/*
* ILU.cs
* 
* Copyright (c) 2005, dnAnalytics. All rights reserved.
*/

#region Using Directives
using System;
using dnAnalytics.LinearAlgebra;
using dnAnalytics.Math;
using dnAnalytics.Exceptions;
#endregion

namespace dnAnalytics.LinearAlgebra.Decomposition
{
    /// <summary>
    /// Interface for computing the LU factorization of an n by n <see cref="Matrix"/>.
    /// </summary>
    internal interface ILU : IAlgorithm
    {
        /// <summary>
        /// Returns a value indicating whether the matrix is singular.
        /// </summary>
        /// <returns><b>true</b> if the matrix is singular; otherwise, <b>false</b>.</returns>
        bool IsSingular();

        /// <summary>
        /// Returns the lower factor of the factorization.
        /// </summary>
        /// <returns>The lower factor of the factorization.</returns>
        Matrix LowerFactor();

        /// <summary>
        /// Places the lower factor in the result <see cref="Matrix"/>.
        /// </summary>
        /// <param name="result">The <see cref="Matrix"/> to store the lower factor in.</param>
        void LowerFactor(Matrix result);

        /// <summary>
        /// Returns the upper factor of the factorization.
        /// </summary>
        /// <returns>The upper factor of the factorization.</returns>
        Matrix UpperFactor();

        /// <summary>
        /// Places the upper factor in the result <see cref="Matrix"/>.
        /// </summary>
        /// <param name="result">The <see cref="Matrix"/> to store the lower factor in.</param>
        void UpperFactor(Matrix result);

        /// <summary>
        /// The determinant of the matrix.
        /// </summary>
        /// <returns>The determinant of the matrix.</returns>
        double Determinant();

        /// <summary>
        /// Returns the inverse of the matrix.
        /// </summary>
        /// <returns>The inverse of the matrix.</returns>
        Matrix Inverse();

        /// <summary>
        /// Places the inverse of the matrix in to the result matrix.
        /// </summary>
        /// <param name="result">The matrix to place the inverse into.</param>
        void Inverse(Matrix result);

        /// <summary>
        /// Returns an <b>int</b> array indicating which rows were interchanged during factorization.
        /// Row i was interchanged with row pivots[i].</summary>
        /// <value>An <b>int</b> array indicating which rows were interchanged during factorization.</value>
        int[] Pivots();

        /// <summary>
        /// Estimates the reciprocal the L1 norm condition number of the matrix. The number is calculated 
        /// as ||A|| * ||AInverse|| where ||.|| is the L1 norm.
        /// </summary>
        /// <returns>The reciprocal the L1 norm condition number of the matrix</returns>
        double L1NormConditionNumber();

        /// <summary>
        /// Estimates the reciprocal the infinity norm condition number of the matrix. The number is calculated 
        /// as ||A|| * ||AInverse|| where ||.|| is the infinity norm.
        /// </summary>
        /// <returns>The reciprocal the infinity norm condition number of the matrix</returns>
        double InfinityNormConditionNumber();

        /// <summary>
        ///  Solves a system of linear equations, <b>AX = B</b>.
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
        /// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
        Matrix Solve(Matrix rightHandSide);

        /// <summary>
        /// Solves a system of linear equations, <b>AX = B</b>.
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
        /// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
        void Solve(Matrix rightHandSide, Matrix result);

        /// <summary>
        /// Solves a system of linear equations, <b>Ax = b</b>.
        /// </summary>
        /// <param name="rightHandSide">The right hand side vector, <b>b</b>.</param>
        /// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
        Vector Solve(Vector rightHandSide);

        /// <summary>
        /// Solves a system of linear equations, <b>Ax = b</b>.
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Vector"/>, <b>b</b>.</param>
        /// <param name="result">The left hand side <see cref="Vector"/>, <b>x</b>.</param>
        void Solve(Vector rightHandSide, Vector result);
    }
}
